package me.yczhang.data_structure.range;

import java.util.Iterator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * Created by YCZhang on 12/4/15.
 */
public class LongRange extends Range implements Iterable<Long> {

	protected class LongRangeIter implements Iterator<Long> {
		protected long from;
		protected long util;
		protected long skip;
		protected long next;

		protected LongRangeIter(long from , long util, long skip) {
			this.from = from;
			this.util = util;
			this.skip = skip;
			this.next = from;
		}

		@Override
		public boolean hasNext() {
			return this.from > this.util ? this.next > this.util : this.next < this.util;
		}

		@Override
		public Long next() {
			if (hasNext()) {
				long ret = this.next;
				this.next += this.skip;
				return ret;
			}
			else {
				throw new OutOfRangeException(this.from, this.util, this.next);
			}
		}
	}

	protected long from;
	protected long util;
	protected long skip;

	protected LongRange(long from, long util) {
		this(from, util, from > util ? -1 : 1);
	}

	protected LongRange(long from, long util, long skip) {
		if (skip == 0)
			throw new IllegalArgumentException("skip == 0");
		if (from < util && skip < 0)
			throw new IllegalArgumentException("from < util but skip < 0");
		if (from > util && skip > 0)
			throw new IllegalArgumentException("from > util but skip > 0");

		this.from = from;
		this.util = util;
		this.skip = skip;
	}

	@Override
	public Iterator<Long> iterator() {
		return new LongRangeIter(this.from, this.util, this.skip);
	}

	public Stream<Long> stream() {
		return StreamSupport.stream(spliterator(), false);
	}
}
